#include "Session.h"
#include <functional>

Session::Session(std::shared_ptr<tcp::socket> socket)
:_socket(socket),_send_pending(false),_recv_pending(false)
{

}
Session::~Session()
{

}

// 作为客户端的时候连接到服务器
void Session::Connect(const tcp::endpoint &endpoint)
{
    _socket->connect(endpoint);
}


void Session::WriteCallBackErr(const boost::system::error_code &ec,std::size_t bytes_transferred,std::shared_ptr<MsgNode> sendNode)
{
    if (ec)
    {
        std::cout<<"WriteToSocketErr ErrorValue:"<<ec.value()<<" ErrorMessage:"<<ec.message()<<std::endl;
        return;
    }
    if (_send_Node->_cur_len+bytes_transferred < sendNode->_total_len)
    {
         _socket->async_write_some(boost::asio::buffer(_send_Node->_msg+_send_Node->_cur_len,_send_Node->_total_len-_send_Node->_cur_len),
                        std::bind(&Session::WriteCallBackErr,this,std::placeholders::_1,std::placeholders::_2,sendNode));
    }
    
    sendNode->_cur_len += bytes_transferred;

}
void Session::WriteToSocketErr(const std::string & buf)
{
    _send_Node = std::make_shared<MsgNode>(buf.c_str(),buf.size());
    _socket->async_write_some(boost::asio::buffer(_send_Node->_msg+_send_Node->_cur_len,_send_Node->_total_len-_send_Node->_cur_len),
        std::bind(&Session::WriteCallBackErr,this,std::placeholders::_1,std::placeholders::_2,_send_Node));
}


void Session::WriteCallBack(const boost::system::error_code &ec,std::size_t bytes_transferred)
{
    if(ec)
    {
        std::cout<<"WriteCallBack ErrorValue:"<<ec.value()<<" ErrorMessage:"<<ec.message()<<std::endl;
        return;
    }
    auto msgNode = _send_queue.front();
    if (msgNode->_cur_len+bytes_transferred < msgNode->_total_len)
    {
        msgNode->_cur_len += bytes_transferred;
        _socket->async_write_some(boost::asio::buffer(msgNode->_msg+msgNode->_cur_len,msgNode->_total_len-msgNode->_cur_len),
                                            std::bind(&Session::WriteCallBack,this,std::placeholders::_1,std::placeholders::_2));

    }
    else{
        _send_queue.pop();
        //如果队列中还有数据，继续执行写操作
        if (_send_queue.size() > 0)
        {
            msgNode = _send_queue.front();
            _socket->async_write_some(boost::asio::buffer(msgNode->_msg+msgNode->_cur_len,msgNode->_total_len-msgNode->_cur_len),
                                            std::bind(&Session::WriteCallBack,this,std::placeholders::_1,std::placeholders::_2));
        }
        else{
            _send_pending = false;
        }
    }
    
}

void Session::WriteToSocket(const std::string & buf)
{
    auto msgNode = std::make_shared<MsgNode>(buf.c_str(),buf.size());
    _send_queue.push(msgNode);
    if(!_send_pending)
    {
        _socket->async_write_some(boost::asio::buffer(msgNode->_msg,msgNode->_total_len),
                        std::bind(&Session::WriteCallBack,this,std::placeholders::_1,std::placeholders::_2));
        //有需要执行的写操作，设置_send_pending为true
        _send_pending = true;
    }
}

void Session::WriteAllToSocket(const std::string & buf)
{
    _send_Node = std::make_shared<MsgNode>(buf.c_str(),buf.size());
    _send_queue.push(_send_Node);
    if(_send_pending) return;

    boost::asio::async_write(*_socket,boost::asio::buffer(_send_Node->_msg+_send_Node->_cur_len,_send_Node->_total_len-_send_Node->_cur_len),
                        std::bind(&Session::WriteAllCallBack,this,std::placeholders::_1,std::placeholders::_2));
    _send_pending = true;
}
void Session::WriteAllCallBack(const boost::system::error_code &ec,std::size_t bytes_transferred)
{
    if (ec)
    {
        std::cout<<"WriteAllCallBack ErrorValue:"<<ec.value()<<" ErrorMessage:"<<ec.message()<<std::endl;
        return;
    }

    _send_queue.pop();
    if (_send_queue.size() > 0)
    {
        auto msgNode = _send_queue.front();
        boost::asio::async_write(*_socket,boost::asio::buffer(msgNode->_msg+msgNode->_cur_len,msgNode->_total_len-msgNode->_cur_len),
                        std::bind(&Session::WriteAllCallBack,this,std::placeholders::_1,std::placeholders::_2));
    }
    else
    {
        _send_pending = false;
    }
    

    
}

void Session::ReadFromSocket()
{
    if(_recv_pending) return;
    auto _recv_Node = std::make_shared<MsgNode>(RECVSIZE);
    _socket->async_read_some(boost::asio::buffer(_recv_Node->_msg+_recv_Node->_cur_len,_recv_Node->_total_len-_recv_Node->_cur_len),
                        std::bind(&Session::ReadCallBack,this,std::placeholders::_1,std::placeholders::_2));
    _recv_pending = true;
}

void Session::ReadCallBack(const boost::system::error_code& ec,
        std::size_t bytes_transferred)
{
    if(ec)
    {
        std::cout<<"ReadCallBack ErrorValue:"<<ec.value()<<" ErrorMessage:"<<ec.message()<<std::endl;
        return;
    }
    _recv_Node->_cur_len += bytes_transferred;
    if (_recv_Node->_cur_len < _recv_Node->_total_len)
    {
        _socket->async_read_some(boost::asio::buffer(_recv_Node->_msg+_recv_Node->_cur_len,_recv_Node->_total_len-_recv_Node->_cur_len),
                        std::bind(&Session::ReadCallBack,this,std::placeholders::_1,std::placeholders::_2));
    }
    else
    {
        _recv_pending = false;
        _recv_Node=nullptr;


    }
    
}


void Session::ReadAllFromSocket()
{
    if(_recv_pending) return;
    _recv_Node = std::make_shared<MsgNode>(RECVSIZE);
    boost::asio::async_read(*_socket,boost::asio::buffer(_recv_Node->_msg+_recv_Node->_cur_len,_recv_Node->_total_len-_recv_Node->_cur_len),
                        std::bind(&Session::ReadAllCallBack,this,std::placeholders::_1,std::placeholders::_2));
    _recv_pending = true;
}
void Session::ReadAllCallBack(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
    if(ec)
    {
        std::cout<<"ReadAllCallBack ErrorValue:"<<ec.value()<<" ErrorMessage:"<<ec.message()<<std::endl;
        return;

    }
    _recv_Node->_cur_len +=bytes_transferred;
    _recv_pending = false;
    _recv_Node=nullptr;
    
}